using System.Collections;
using System.Collections.Generic;
using System.IO;
using Commons.Models.Settings;
using Commons.Models.Settings.Parsers;
using System;
using Commons.Utils;

namespace Commons.Loading
{
	public class SettingsLoadingTask : BasicLoadingTask
	{
		private List<ISettingsParser> parsers;

		public SettingsLoadingTask(float weight)
			: base(weight)
		{
		}

		public override void SetUp()
		{
			parsers = new List<ISettingsParser>();
			parsers.Add(new GeneralSettingsParser());
		}

		public override IEnumerator Update()
		{
			if (SettingsModel.Instance == null)
			{
				SettingsModel settingsModel = new SettingsModel();

				ParserContext context = new ParserContext(settingsModel);
				ParserContextHolder.Context = context;

				try
				{
					settingsModel.AddSetting(new LockSettings());

					foreach (ISettingsParser parser in parsers)
					{
						try
						{
							parser.Load();
						}
						catch(Exception e)
						{
							Console.WriteLine(string.Format("Error while loading {0}: {1}", parser.GetType().Name, e.Message));
							throw e;
						}

						yield return null;

						IEnumerator parseEnum = CollectionsHelper.SafeEnumerator(parser.Parse(context, settingsModel), (e) => {
							Console.WriteLine(string.Format("Error while parsing {0}: {1}", parser.GetType().Name, e.Message));
						});

						while (parseEnum.MoveNext())
						{
							yield return parseEnum.Current;
						}

						yield return null;
					}
                	//success = true;
				}
				finally
				{
					ParserContextHolder.Context = null;
				}

				SettingsModel.Instance = settingsModel;
			}
		}

		public override float Progress
		{
			get
			{
				if (Completed)
				{
					return 1.0f;
				}
				else if (parsers != null && parsers.Count > 0)
				{
					float acumProgress = 0.0f;

					foreach (ISettingsParser parser in parsers)
					{
						if (parser.TotalObjects > 0)
						{
							acumProgress += (float) parser.NumObjects / parser.TotalObjects;
						}
					}

					return acumProgress / parsers.Count;
				}
				else
				{
					return 0.0f;
				}
			}
		}
	}
}

